package advanced.design_mode.singletonmode;


/**
 * 单例模式:
 * <p>
 * SingletonMode : 该案例使用懒汉式套路,  在多线程环境下,对外只存在一个对象
 * <p>
 * 饿汉式: 线程安全, 调用效率高, 但是, 不能延迟加载
 * 懒汉式: 线程安全, 调用效率不高, 可以延迟加载
 * <p>
 * 静态内部类的方式,结合两者的优点!!!
 *
 * <p>
 * 1. 构造器私有化, --> 避免了外部的new 构造器
 * 2. 提供私用的静态属性 ---> 存储对象的地址
 * 3. 提供公共的静态化方法, -->获取属性
 */
public class SingletonMode {
    //饿汉式, 不需要加同步关键字, 天然线程安全,  类初始化的时候就
    //创建了这个类的对象, 效率高
    //    private volatile static SingletonMode instance=new SingletonMode();//饿汉式
    // 提供私有的静态属性
    private volatile static SingletonMode instance; //双重检测, 可能会出现指令重排,导致null错误, volatile 保证数据及时更新

    // 构造器私有化
    private SingletonMode() {
    }

    //懒汉式
    //提供公共的静态方法,-->获取属性,创建唯一对象
    public static SingletonMode newInstance() {
        //双重检测, 优化并发量大的时候程序的等待耗时  很重要!!!
        if (null != instance) return instance;
        //多个线程进行资源锁控制, 保证线程安全
        synchronized (SingletonMode.class) {
            if (null == instance) instance = new SingletonMode();
        }

        return instance;
    }

    /**
     * 静态内部类的方式实现单例模式
     */
    private static class SingletonClassInstance {
        private static final SingletonMode sm = new SingletonMode();
    }

    public static SingletonMode getInstance() {
        return SingletonClassInstance.sm;
    }

    public static void main(String[] args) {
        SingletonMode l2 = SingletonMode.newInstance();
        SingletonMode l21 = SingletonMode.newInstance();
        SingletonMode l22 = SingletonMode.getInstance();
        System.out.println(l2);
        System.out.println(l21);
        System.out.println(l22);
    }
}
